﻿// <copyright file="StoryboardExtensions.cs" company="Ucaya">
// </copyright>
// <author>Ucaya</author>

namespace Channel9Kinect
{
    #region

    using System;
    using System.Linq;
    using System.Windows;
    using System.Windows.Media.Animation;

    #endregion

    public static class StoryboardExtensions
    {
        // Using a DependencyProperty as the backing store for TargetProperty.  This enables animation, styling, binding, etc...

        #region Constants and Fields

        public static readonly DependencyProperty TargetPropertyProperty = DependencyProperty.RegisterAttached("TargetProperty", typeof(DependencyProperty), typeof(PropertyPath), new PropertyMetadata(TargetPropertyChangedCallback));

        // Using a DependencyProperty as the backing store for SBExtTarget.  This enables animation, styling, binding, etc...
        private static readonly DependencyProperty SBExtTargetProperty = DependencyProperty.RegisterAttached("SBExtTarget", typeof(object), typeof(Storyboard), null);

        #endregion

        #region Public Methods

        public static DoubleAnimationUsingKeyFrames CreateAnim(this Storyboard sb, DependencyObject target, string propertyPath, IEasingFunction easing, double value, TimeSpan keyTime)
        {
            DoubleAnimationUsingKeyFrames doubleAnim = (from anim in sb.Children.OfType<DoubleAnimationUsingKeyFrames>()
                                                        where GetSBExtTarget(anim) == target
                                                        let prop = Storyboard.GetTargetProperty(anim)
                                                        where prop.Path == propertyPath
                                                        select anim).FirstOrDefault();

            if (doubleAnim == null)
            {
                doubleAnim = new DoubleAnimationUsingKeyFrames();
                SetSBExtTarget(doubleAnim, target);
                Storyboard.SetTarget(doubleAnim, target);
                Storyboard.SetTargetProperty(doubleAnim, new PropertyPath(propertyPath));
                sb.Children.Add(doubleAnim);
            }

            var kf = new EasingDoubleKeyFrame();
            kf.EasingFunction = easing;
            kf.KeyTime = keyTime;
            kf.Value = value;
            doubleAnim.KeyFrames.Add(kf);

            return doubleAnim;
        }

        public static DependencyProperty GetTargetProperty(DependencyObject obj)
        {
            return (DependencyProperty)obj.GetValue(TargetPropertyProperty);
        }

        public static void SetTargetProperty(DependencyObject obj, DependencyProperty value)
        {
            obj.SetValue(TargetPropertyProperty, value);
        }

        #endregion

        #region Methods

        private static object GetSBExtTarget(DependencyObject obj)
        {
            return obj.GetValue(SBExtTargetProperty);
        }

        private static void SetSBExtTarget(DependencyObject obj, object value)
        {
            obj.SetValue(SBExtTargetProperty, value);
        }

        private static void TargetPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (e.NewValue == null)
            {
                d.ClearValue(Storyboard.TargetPropertyProperty);
            }
            else
            {
                Storyboard.SetTargetProperty(d, new PropertyPath(e.NewValue));
            }
        }

        #endregion
    }
}